package cn.dai.Reflection.demo;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

/**
 * @author ArkD42
 * @file 1 - Java基础语法
 * @create 2020 - 04 - 23 - 10:04
 */
public class ReflectionTest {

    @Test
    public void getInstanceAllField(){
        Class<Animal> animalClass = Animal.class;

        // 获取本类和父类的所有属性，返回一个属性类实例的数组 本类和父类private修饰的字段是不能被获取到的
        Field[] fields = animalClass.getFields();

        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("-----------------------------------------------------------------");

        // getDeclaredFields(); 当前运行时类的所有属性 没有访问权限限制，仅限本类独有的字段
        Field[] declaredFields = animalClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field);
        }
    }

    @Test
    public void getInstance2(){
        Class<Animal> animalClass = Animal.class;

        Field[] declaredFields = animalClass.getDeclaredFields();
        for (Field field : declaredFields) {
            // 权限修饰访问
            int modifiers = field.getModifiers();//获取访问权限修饰 返回的是一个权限状态值
            String accessModifier = Modifier.toString(modifiers); // 通过这个权限修饰类转换一下

            // 数据类型访问 获取
            Class<?> fieldType = field.getType();
            String fieldTypeName = fieldType.getName();

            // 字段标识名 获取
            String fieldName = field.getName();

            System.out.println(accessModifier + " " + fieldTypeName + " " + fieldName);
        }
    }

    @Test
    public void getMethods(){
        Class<Animal> animalClass = Animal.class;

        // 获取当前运行时类和及其父类，所有public修饰的方法
        Method[] methods = animalClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("-----------------------------------------------------------------");

        // 获取当前运行时类中声明的所有方法，不包含父类
        Method[] declaredMethods = animalClass.getDeclaredMethods();
        for (Method method:declaredMethods) {
            System.out.println(method);
        }
    }

    @Test
    public void getFactor(){
        // 权限修饰，返回类型，方法名，参数，抛出的异常，注解，注解的值
        Class<Animal> animalClass = Animal.class;
        // 获取声明的注解
        Method[] declaredMethods = animalClass.getDeclaredMethods();
        for (Method method:declaredMethods) {

            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation: annotations) {

                System.out.println(annotation); // @cn.dai.Reflection.demo.MyAt(value=中国)
            }

            // 获取方法的权限修饰
            int modifiers = method.getModifiers();
            String accessModifier = Modifier.toString(modifiers);

            // 获取返回类型
            Class<?> returnType = method.getReturnType();
            String returnTypeName = returnType.getName();

            // 获取方法名
            String methodName = method.getName();

            // 获取参数
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (!(parameterTypes == null && parameterTypes.length == 0)){

                for (int i = 0; i < parameterTypes.length; i++) {
                    System.out.println(parameterTypes[i].getName() + "参数" + i);
                }
            }

            // 异常的获取
            Class<?>[] exceptionTypes = method.getExceptionTypes();
            if (exceptionTypes.length > 0){
                for (int i = 0; i < exceptionTypes.length; i++) {
                    System.out.println( exceptionTypes[i].getName() );
                }
            }
        }
    }

    @Test
    public void constructor(){
        Class<Animal> animalClass = Animal.class;

        // 当前运行时类中声明为Public 的构造器
        Constructor[] constructors = animalClass.getConstructors();
        for (Constructor constructor:constructors) {
            System.out.println(constructor);
        }

        System.out.println("--------------------------------------");

        // 当前运行时类自己的构造器,无论权限修饰
        Constructor[] declaredConstructors = animalClass.getDeclaredConstructors();
        for (Constructor constructor: declaredConstructors) {
            System.out.println(constructor);
        }
    }

    @Test
    public void superClass(){
        Class<Animal> animalClass = Animal.class;

        // 仅父类
        Class<? super Animal> superclass = animalClass.getSuperclass();
        System.out.println(superclass);

        // 带泛型的父类
        Type genericSuperclass = animalClass.getGenericSuperclass();
        System.out.println(genericSuperclass);

        ParameterizedType type = (ParameterizedType)genericSuperclass;

        // 多个泛型参数类
        Type[] actualTypeArguments = type.getActualTypeArguments();
        // 取第一个泛型参数类的名字
        System.out.println(((Class)actualTypeArguments[0]).getName());
    }

    @Test
    public void IPA(){
        Class<Animal> animalClass = Animal.class;

        // 接口是多实现的，所有可能有多个存在
        Class<?>[] interfaces = animalClass.getInterfaces();

        for (Class interFace:interfaces) {
            System.out.println(interFace);
        }

        System.out.println("---------------------------------------");

        // 获取父类接口
        Class<?>[] interfaces1 = animalClass.getSuperclass().getInterfaces();

        for (Class interFace:interfaces1) {
            System.out.println(interFace);
        }

        System.out.println("----------------------------------------");

        // 所在包
        Package aPackage = animalClass.getPackage();
        System.out.println(aPackage);

        // 类上的注解
        Annotation[] annotations = animalClass.getAnnotations();
        for (Annotation annotation : annotations){
            System.out.println(annotation);
        }
    }


}
